# This file is part of Neuroinfo Toolkit.
#
# Neuroinfo Toolkit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Neuroinfo Toolkit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Neuroinfo Toolkit.  If not, see <http://www.gnu.org/licenses/>.

import unittest
from neuro.filesystem import *
from neuro.strings import *
from neuro.exceptions import IllegalArgumentException

class TestStrings(unittest.TestCase):
	def setUp(self):
		self._dir = "../../../dat"

	def test_colorize(self):
		## --- no arguments
		self.assertRaises(TypeError, colorize)

		## --- bad first argument
		self.assertRaises(IllegalArgumentException, colorize, list(), "")

		## --- bad first argument
		self.assertRaises(IllegalArgumentException, colorize, list(), "blue")
		self.assertRaises(IllegalArgumentException, colorize, "", "blue")

		## --- bad second argument
		self.assertRaises(IllegalArgumentException, colorize, "foo", list())
		self.assertRaises(IllegalArgumentException, colorize, "foo", "cadmium orange")

		## --- colorize a string
		self.assertEqual(colorize("  fOoBaR ", "  rEd    "), "\x1b[31mfOoBaR\x1b[0m")

	def test_stylize(self):
		## --- no arguments
		self.assertRaises(TypeError, stylize)

		## --- bad first argument
		self.assertRaises(IllegalArgumentException, stylize, list(), "")

		## --- bad first argument
		self.assertRaises(IllegalArgumentException, stylize, list(), "blink")
		self.assertRaises(IllegalArgumentException, stylize, "", "blink")

		## --- bad second argument
		self.assertRaises(IllegalArgumentException, stylize, "foo", list())
		self.assertRaises(IllegalArgumentException, stylize, "foo", "4-D rotate")

		## --- stylize a string
		self.assertEqual(stylize("  fOoBaR ", "  bLinK    "), "\x1b[5mfOoBaR\x1b[0m")

	def test_explode(self):
		## --- no arguments
		self.assertRaises(TypeError, explode)

		## --- bad first argument
		self.assertRaises(IllegalArgumentException, explode, list(), ",")
		self.assertRaises(IllegalArgumentException, explode, "", ",")

		## --- bad second argument
		self.assertRaises(IllegalArgumentException, explode, "Hello, World!", list())
		self.assertRaises(IllegalArgumentException, explode, "Hello, World!", "")

		## --- bad third argument
		self.assertRaises(IllegalArgumentException, explode, "Hello, World!", ",", list())

		## --- explode multi-item string, no trim
		self.assertEqual(explode("  Hello, World!  ", ","), ["  Hello", " World!  "])

		## --- explode multi-item string, with trim
		self.assertEqual(explode("  Hello, World!  ", ",", True), ["Hello", "World!"])

		## --- explode with one-item string, no trim
		self.assertEqual(explode("  1  ", ","), ["  1  "])

		## --- explode one-item string, with trim
		self.assertEqual(explode("  1  ", ",", True), ["1"])

	def test_regex(self):
		self.assertRaises(TypeError, regex)

		## --- bad first argument (regexp)
		self.assertRaises(IllegalArgumentException, regex, list(), "foobar")
		self.assertRaises(IllegalArgumentException, regex, "", "foobar")

		## --- bad second argument (string)
		self.assertRaises(IllegalArgumentException, regex, ".*", list())
		self.assertRaises(IllegalArgumentException, regex, ".*", "")

		## ---bad regexp
		self.assertRaises(RegularExpressionException, regex, "#$%*)", "string")

		## --- check various strings against regular expressions
		self.assertFalse(regex("foo.*", "bar"), False)
		self.assertTrue(regex(".*", "foobar"))
		self.assertEqual(regex("(.*)", "foobar"), ("foobar",))
		self.assertEqual(regex("(.*)", " foo bar "), (" foo bar ",))
		self.assertEqual(regex("(.*) bar", "foo bar"), ("foo",))
		self.assertEqual(regex("(.*) (.*)", "foo bar"), ("foo", "bar"))

		string = '''foo bar biz
					bat bam bit'''
		self.assertEqual(regex("foo.*bam\s(.*)", string), ("bit",))


	def test_urlencode(self):
		self.basic(urlencode)
		self.assertEqual(urlencode(" Hello, World! "), "Hello%2C+World%21")

	def test_toArray(self):
		## --- no arguments
		self.assertRaises(TypeError, toArray)

		## --- get some data
		data = fileGetContents(os.path.join(self._dir, "strings", "example.csv"))

		## --- bad first argument
		self.assertRaises(IllegalArgumentException, toArray, string="", row="\n", col=" ", strip=True)
		self.assertRaises(IllegalArgumentException, toArray, string=list(), row="\n", col=" ", strip=True)

		## --- bad second argument
		self.assertRaises(IllegalArgumentException, toArray, string=data, row="", col=" ", strip=True)
		self.assertRaises(IllegalArgumentException, toArray, string=data, row=list(), col=" ", strip=True)

		## --- bad third argument
		self.assertRaises(IllegalArgumentException, toArray, string=data, row="\n", col="", strip=True)
		self.assertRaises(IllegalArgumentException, toArray, string=data, row="\n", col=list(), strip=True)

		## --- bad fourth argument
		self.assertRaises(IllegalArgumentException, toArray, string=data, row="\n", col=" ", strip="")
		self.assertRaises(IllegalArgumentException, toArray, string=data, row="\n", col=" ", strip=list())

		## --- array a single element string
		a = toArray("a", row="\n", col=" ", strip=True)
		self.assertEqual(a[0][0], "a")

		## --- parse csv to array
		a = toArray(data, row="\n", col=" ", strip=True)
		self.assertEqual(a, [[".1", ".2", ".4"],	["aa", "b", ".22"],
							 ["09", "74", ".123"],	[".45", "12", "103"],
							 ["a", "b", "count"]])

		## --- don't strip list items
		a = toArray(data, row="\n", col=" ")
		self.assertEqual(a, [[".1", "\t.2", ".4"],	["aa", "b", ".22"],
							 ["09", "74", ".123"],	[".45", "12", "103"],
							 ["a", "b", "count"]])

	def test_removeBlankLines(self):
		self.assertRaises(TypeError, removeBlankLines)

		## --- empty string
		self.assertRaises(IllegalArgumentException, removeBlankLines, "")

		## --- basically an empty string
		self.assertRaises(IllegalArgumentException, removeBlankLines, "\n  ")
		
		## --- remove blank line from multiline string
		a = "abcd\n\nefgh"
		b = removeBlankLines(a)
		self.assertEqual(b, "abcd\nefgh")

		## --- remove blank line containing whitespace without collapse
		a = "abc\n  \nefg"
		b = removeBlankLines(a, collapse=False)
		self.assertEqual(b, "abc\n  \nefg")

		## --- remove blank line containing whitespace without collapse
		a = "abc\n  \nefg"
		b = removeBlankLines(a, collapse=True)
		self.assertEqual(b, "abc\nefg")
		
	def basic(self, method):
		## --- no arguments
		self.assertRaises(TypeError, method)

		## --- bad argument
		self.assertRaises(IllegalArgumentException, method, None)
		self.assertRaises(IllegalArgumentException, method, "")

	def tearDown(self):
		pass

unittest.main()